home *** CD-ROM | disk | FTP | other *** search
- /************************************************************************/
- /* */
- /* netstat.c */
- /* */
- /* Durch bloßes Ändern der Extension im Dateinamen, läßt sich Pro- */
- /* gramm als normale GEM-Anwendung oder aber als Accessory betrei- */
- /* ben. */
- /* */
- /* Copyright (c) FORTEC/pm 1993 */
- /* */
- /************************************************************************/
-
- /* -------------------------------------------------------------------- */
- /* Headerdateien einbinden. */
- /* -------------------------------------------------------------------- */
-
- #include <aes.h>
- #include <stdio.h>
- #include <tos.h>
- #include <vdi.h>
- #include <string.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <time.h>
- #include <ext.h>
- #include "cookie.h"
- #include "tcp.h"
- #include "queue.h"
- #include "inetcust.h"
- #include "udp.h"
- #include "tuwtcp.h"
- #include "nicmem.h"
- #include "pktqueue.h"
-
- #define tcp_stat(a,b) gemdos(635,a,b)
-
- #define TELNET 23
- #define FTP_CTL 21
- #define FTP_DATA 20
-
- #define NAMESERV_IEN116 42
- #define NAMESERV_RFC 53
-
- int print_tcb( TCP_TCB *);
- int print_udp( UDP_CTL *);
- char *pr_state(int);
- char *pr_tcpport(int,char*);
- char *pr_udpport(int,char*);
- void netstat(void);
- void print_ipq(PKTQUEUE* q);
- char *pr_ipprot(int prot);
- void mouse_on(void);
- void mouse_off(void);
- void print_pktbuf(PKTPOOL * p);
-
- typedef struct
- {
- long st_sent;
- long st_xmiterr;
- long st_collision;
- long st_got;
- long st_received;
- long st_missed;
- long st_crc;
- int st_err;
- int st_free;
- long st_intr;
- } et_stat;
-
- #define LINESIZE 70L
- #define NUMLINES 40
-
- #define WINW 500
- #define WINH 350
- #define ZH 6
-
- #define mmin(a,b) (((a) < (b)) ? (a) : (b))
-
- TCPSTAT tstat;
-
- char *myid = "@(#)TUW-Netstat 1.1 pm";
-
- int x, y,
- kstate,
- key,
- clicks,
- event,
- state;
- int pipe[8];
- int quit;
-
- char log_text[NUMLINES][LINESIZE+1];
- char text[2*LINESIZE];
- int line_tab[NUMLINES];
- int actline = 0;
-
- #define LPR_PORT 515
-
- /* -------------------------------------------------------------------- */
- /* Extern definierte globale Variablen. */
- /* -------------------------------------------------------------------- */
- /* Mittels dieser Variablen kann */
- extern int _app; /* das Programm feststellen, ob es */
- /* als Accessory oder normale App- */
- /* likation gestartet wurde. */
- extern int flag;
- extern int fhandle;
- extern char path[];
- extern long oldgem;
- extern long grpgem;
-
- /* -------------------------------------------------------------------- */
- /* Globale Variablen. */
- /* -------------------------------------------------------------------- */
- int get_response(void);
- void output1(int o_len, char *o_str);
- void output(char *o_str);
- void printfile(FILE *fin);
- int connect(char * host, int port);
- void redraw_window( int all,int x,int y,int w,int h );
- int handle_message(int *pipe);
- void multi( void );
- void event_loop( void );
- void spool(void);
-
- int whandle; /* Handle für geöffnetes Fenster. */
- char title[] = "TUW-Netstat 1.0"; /* Titelzeile des Fensters. */
- int gl_wchar; /* Größe und Breite eines Buchsta- */
- int gl_hchar; /* ben (wichtig falls mit unter- */
- int gl_wbox; /* schiedlichen Bildschirmauflö- */
- int gl_hbox; /* sungen gearbeitet wird) bzw. */
- /* einer Box. */
- int phys_handle; /* Handles für GEM und VDI. */
- int handle;
- int max_x; /* Maximale Größe der Arbeitsfläche */
- int max_y;
- int appl_id; /* Identifikationsnummer des Prog. */
- int menu_id; /* Id.-nummer im Menü 'Desk'. */
-
- int line_height = 8;
- int cell_width = 8;
-
- int dum;
- int x,y,w,h;
- int attrib[10];
-
- int scroll_log(int actline)
- { /* rotate log lines */
- int i;
- int line;
-
- if(actline < NUMLINES-1) return(actline+1);
- line = line_tab[0];
- for(i=0; i<NUMLINES-1; i++)
- {
- line_tab[i] = line_tab[i+1];
- }
- line_tab[NUMLINES-1] = line;
- return(NUMLINES-1);
- }
-
- int log(char *str)
- {
- int i,ii,ilen;
- char *s;
- int len,inline;
-
- if(!str) return(0);
- len = (int)strlen(str);
- if(str[len-1] == '\r')
- {
- str[len-1] = 0;
- inline = 1;
- len--;
- }
- else inline = 0;
- ilen = 0;
-
- log_text[line_tab[actline]][0] = 0;
- if(!len)
- actline = scroll_log(actline);
- s = log_text[line_tab[actline]];
- while(len > 0)
- {
- for(i=0; i <= LINESIZE; i++)
- {
- if(str[ilen] == '\f')
- {
- ilen++;
- len--;
- for(ii = actline; ii < NUMLINES; ii++) /* init log table */
- {
- log_text[ii][0] = 0;
- }
- for(ii = 0; ii < NUMLINES; ii++)
- line_tab[ii] = ii;
- actline = 0;
- s = log_text[line_tab[0]];
- inline = 1;
- }
- else
- {
- *s++ = str[ilen];
- }
- if(!str[ilen])
- break;
- ilen++;
- len--;
- }
- if(!inline) *s=0;
- if(!inline) actline = scroll_log(actline);
- if(!inline) s = log_text[line_tab[actline]];
- }
- return(1);
- }
-
- void open_window( void )
- {
- if(whandle <= 0)
- {
- whandle = wind_create(NAME|CLOSER|MOVER, 0, 0, max_x + 1, max_y + 1 );
- if( whandle <= 0 )
- return;
-
- wind_set(whandle, WF_NAME, title);
- vst_font(handle, 1); /* auswählen */
- vst_height(handle, ZH, &dum,&dum,&cell_width,&line_height); /* set small font */
- vqt_attributes( handle, attrib );
- vst_alignment(handle, 0, 4, &dum, &dum);
- wind_calc(WC_BORDER, NAME|CLOSER|MOVER , 40, 40, cell_width*LINESIZE, line_height*NUMLINES, &x, &y, &w, &h);
- wind_open(whandle, x,y,w,h+15);
- }
- else
- wind_set( whandle, WF_TOP );
- }
-
- /* -------------------------------------------------------------------- */
- /* min() */
- /* */
- /* Minimum zweier Zahlen berechnen. */
- /* -------------------------------------------------------------------- */
-
- int min( int a, int b)
- {
- if( a > b )
- return( b );
- else
- return( a );
- }
-
- /* -------------------------------------------------------------------- */
- /* max() */
- /* */
- /* Maximum zweier Zahlen bestimmen. */
- /* -------------------------------------------------------------------- */
-
- int max( int a, int b)
- {
- if( a < b )
- return( b );
- else
- return( a );
- }
-
- /* -------------------------------------------------------------------- */
- /* rc_intersect() */
- /* */
- /* Schnittfläche zweier Rechtecke berechnen. */
- /* -------------------------------------------------------------------- */
-
- int rc_intersect(GRECT *r1, GRECT *r2)
- {
- int xl, yu, xr, yd; /* left, upper, right, down */
-
- xl = max( r2->g_x, r1->g_x );
- yu = max( r2->g_y, r1->g_y );
- xr = min( (r2->g_x + r2->g_w), (r1->g_x + r1->g_w) );
- yd = min( (r2->g_y + r2->g_h), (r1->g_y + r1->g_h) );
-
- r2->g_x = xl;
- r2->g_y = yu;
- r2->g_w = xr - xl;
- r2->g_h = yd - yu;
-
- return( r2->g_w > 0 && r2->g_h > 0 );
- }
-
- /* -------------------------------------------------------------------- */
- /* mouse_on() */
- /* */
- /* Mauszeiger anschalten. */
- /* -------------------------------------------------------------------- */
-
- void mouse_on(void)
-
- {
- graf_mouse( M_ON, (void *)0 );
- }
-
- /* -------------------------------------------------------------------- */
- /* mouse_off() */
- /* */
- /* Mauszeiger ausschalten. */
- /* -------------------------------------------------------------------- */
-
- void mouse_off(void)
- {
- graf_mouse( M_OFF, (void *)0 );
- }
- /* -------------------------------------------------------------------- */
- /* redraw_window() */
- /* */
- /* Fensterinhalt neu zeichnen, nachdem er zuvor aus irgendeinem */
- /* Grunde zerstört wurde, oder weil das Fenster neu geöffnet wurde. */
- /* -------------------------------------------------------------------- */
-
- void redraw_window( int all,int x,int y,int w,int h )
- {
- GRECT box,
- work;
- int clip[4], r[4];
- int line,dum;
- int i, width,height;
-
- if( whandle <= 0 ) /* Wenn kein Fenster auf ist, */
- return; /* braucht auch nicht gezeichnet */
- /* zu werden. */
- wind_update(BEG_UPDATE);
- /* mouse_off();*/
-
- vsf_color( handle, 0 ); /* set white fill */
- vswr_mode( handle, 1 ); /* set replace mode */
- vst_height( handle, 6, &dum,&dum,&width,&height); /* set small font */
-
- wind_get( whandle, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w, &work.g_h );
- wind_get( whandle, WF_FIRSTXYWH, &box.g_x, &box.g_y, &box.g_w,
- &box.g_h );
-
- while ( box.g_w > 0 && box.g_h > 0 )
- {
- if( rc_intersect( &work, &box ) )
- {
- clip[0] = box.g_x;
- clip[1] = box.g_y;
- clip[2] = box.g_x + box.g_w - 1;
- clip[3] = box.g_y + box.g_h - 1;
-
- vs_clip( handle, 1, clip );
- if( all )
- vr_recfl( handle, clip );
- /* fill rectangle */
-
- for(line=0;line < NUMLINES; line++)
- {
- i = strlen(log_text[line_tab[line]]);
- v_gtext( handle, work.g_x, work.g_y + 15 + (line*height),log_text[line_tab[line]]);
- if(!all)
- {
- r[0] = work.g_x + (width*i);
- r[1] = work.g_y + 15 + (line*height);
- r[2] = r[0] + ((LINESIZE-i)*width) - 1;
- r[3] = r[1] - height + 1;
- vr_recfl(handle,r);
- }
- }
- vs_clip( handle, 0, clip );
- }
- wind_get( whandle, WF_NEXTXYWH, &box.g_x, &box.g_y, &box.g_w,
- &box.g_h );
- }
- /* mouse_on();*/
- wind_update(END_UPDATE);
- }
-
- /* -------------------------------------------------------------------- */
- /* handle_message() */
- /* */
- /* Auswertung der Ereignisse des Multi-Events bezüglich des Message- */
- /* buffers. */
- /* -------------------------------------------------------------------- */
-
- int handle_message(int *pipe)
- {
- switch ( pipe[0] )
- {
- case WM_REDRAW:
- if( pipe[3] == whandle )
- {
- mouse_off();
- redraw_window(1,pipe[4], pipe[5], pipe[6], pipe[7]);
- mouse_on();
- }
- break;
-
- case WM_TOPPED:
- if( pipe[3] == whandle )
- wind_set( whandle, WF_TOP );
- break;
-
- case WM_CLOSED:
- if( pipe[3] == whandle )
- {
- wind_close( whandle );
- wind_delete( whandle );
- whandle = 0;
- }
- if( _app )
- return(1);
- break;
-
- case WM_MOVED:
- case WM_SIZED:
- if( pipe[3] == whandle )
- wind_set( whandle, WF_CURRXYWH, pipe[4], pipe[5],
- pipe[6], pipe[7] );
- break;
-
- case AC_OPEN:
- if( pipe[4] == menu_id )
- open_window();
- break;
-
- case AC_CLOSE:
- if( pipe[3] == menu_id )
- whandle = 0;
- break;
- }
- return(0);
- }
-
- /* -------------------------------------------------------------------- */
- /* event_loop() */
- /* */
- /* Die Multi-Event-Schleife. */
- /* -------------------------------------------------------------------- */
-
- void event_loop( void )
- {
- quit = 0;
- do
- {
- event = evnt_multi( MU_MESAG | MU_TIMER,
- 2, 0x1, 1,
- 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0,
- pipe,
- 1000, 0,
- &x, &y, &state, &kstate, &key, &clicks );
-
- if( event & MU_TIMER)
- {
- netstat();
- }
-
- if( event & MU_MESAG)
- quit = handle_message( pipe );
-
- }
- while (!quit);
- }
-
- /* -------------------------------------------------------------------- */
- /* main() */
- /* */
- /* Kernstück des Programms. */
- /* -------------------------------------------------------------------- */
-
- int main( void )
- {
- int i;
- int work_in[11];
- int work_out[57];
-
- /* ----------------------------------------------------------------- */
- /* Initialization */
- /* ----------------------------------------------------------------- */
-
- appl_id = appl_init();
- if( appl_id != -1 )
- {
- for (i = 0; i < 10; i++)
- work_in[i] = 1;
- work_in[10] = 2;
- phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox,
- &gl_hbox );
- whandle = 0;
- handle = phys_handle;
- v_opnvwk( work_in, &handle, work_out );
- for(i=0; i< NUMLINES; i++) /* init log table */
- {
- line_tab[i] = i;
- log_text[i][0] = 0;
- }
- actline = 0;
- if( handle != 0 )
- {
- max_x = work_out[0];
- max_y = work_out[1];
-
- if( !_app )
- {
- menu_id = menu_register( appl_id, " Netstat" );
- /*open_window();*/
- }
- else
- {
- graf_mouse( 0, (void*)0 );
- open_window();
- }
- /* ----------------------------------------------------------------- */
- /* Event Loop */
- /* ----------------------------------------------------------------- */
-
- event_loop();
-
- /* ----------------------------------------------------------------- */
- /* Deinitialization */
- /* ----------------------------------------------------------------- */
-
- v_clsvwk( handle );
- }
- appl_exit();
- }
- return(0);
- }
-
- /* -------------------------------------------------------------------- */
- /* End of NETSTAT.C */
- /* -------------------------------------------------------------------- */
-
- void netstat()
- {
- COOKIE *cookie;
- long (**tmp)(long,char*);
- INETSTAT *pi;
- et_stat statusblock;
- TCP_TCB *tcb_list;
- PKTQUEUE *q;
- UDP_CTL *udp_list;
-
- log("\f");
- cookie = get_cookie(PKTCOOKIE);
- if(!cookie || !cookie->val)
- {
- log("Packetdriver not installed");
- }
- else
- {
- tmp = (int(**)(long,char*))(cookie->val);
- log("Packet driver statistics:");
- log("-------------------------");
-
- (tmp[NETINFO])(sizeof(statusblock),(char*)&statusblock);
-
- sprintf(text,"%8ld packets sent",statusblock.st_sent);
- log(text);
- sprintf(text,"%8ld xmit errors",statusblock.st_xmiterr);
- log(text);
- sprintf(text,"%8ld collisions",statusblock.st_collision);
- log(text);
- sprintf(text,"%8ld packets got",statusblock.st_got);
- log(text);
- sprintf(text,"%8ld packets received",statusblock.st_received);
- log(text);
- sprintf(text,"%8ld packets missed",statusblock.st_missed);
- log(text);
- sprintf(text,"%8ld crc errors",statusblock.st_crc);
- log(text);
- sprintf(text,"%7xx general status",statusblock.st_err);
- log(text);
- sprintf(text,"%8d packets free",statusblock.st_free);
- log(text);
- sprintf(text,"%8ld interrupts processed",statusblock.st_intr);
- log(text);
- }
- cookie = get_cookie(INETCOOKIE);
- if(!cookie)
- {
- log("TUW-TCP not installed");
- }
- else
- {
- log(" ");
- log("Active connections:");
- log("--------------------");
- pi = (INETSTAT*)(cookie->val);
- /* Original:
- tcb_list = *(pi->tcpcb_list);
- Patch: */
- tcb_list = pi->tcpcb_list==NULL ? NULL : *(pi->tcpcb_list);
- log("hndl local |----- buffers -----|");
- log(" A/P port foreign host.port send/size recv/size state");
- log("-------------------------------------------------------------------");
- log("TCP:");
- while(tcb_list)
- {
- print_tcb(tcb_list);
- tcb_list = tcb_list->next;
- }
- udp_list = *(pi->udp_list);
- log("UDP:");
- while(udp_list)
- {
- print_udp(udp_list);
- udp_list = udp_list->next;
- }
- log(" ");
- log("Protocol statistics recv/sent:");
- log("------------------------------");
- log(" ARP ICMP UDP TCP ");
- sprintf(text," %7ld/%-7ld %7ld/%-7ld %7ld/%-7ld %7ld/%-7ld",
- pi->arp_counts[0], pi->arp_counts[1],
- pi->icmp_counts[0], pi->icmp_counts[1],
- pi->udp_counts[0], pi->udp_counts[1],
- pi->tcp_counts[0], pi->tcp_counts[1]);
- log(text);
- q = (PKTQUEUE*)(**((long***)(cookie->val)+2));
- log(" ");
- log("IP-buffer statistics:");
- log("---------------------");
- print_ipq(q);
- /*
- log(" ");
- log("pktbuffer statistics:");
- log("---------------------");
- print_pktbuf( (PKTPOOL *)(tmp[NETINFO])(0L,(char*)2L));*/
- }
- redraw_window(0,0,0,0,0);
- }
-
- void print_pktbuf(PKTPOOL * p)
- {
- int i;
- char str2[200];
- str2[0]=0;
- sprintf(str2,"%2d-%2d ",p->p_get,p->p_put);
- for(i=0;i<p->p_nbuf;i++)
- {
- sprintf(str2,"%s x%04x:%02x",str2,p->p_tab[i].p_occupied,(ip_head((p->p_tab[i].p_pkt)))->protocol);
- }
- log(str2);
- }
-
- void print_ipq(PKTQUEUE* q)
- {
- PACKET *pq;
- register IP *ip;
- int i;
-
- for(i=0;i<q->q_nbuf;i++)
- {
- if(q->q_tab[i].q_occupied)
- {
- pq = (q->q_tab[i].q_pkt);
- if(pq)
- {
- ip = ip_head(pq);
- sprintf(text,"%6s from %3ld.%3ld.%3ld.%3ld (to %3ld.%3ld.%3ld.%3ld)",
- pr_ipprot((int)ip->protocol),
- ((ip->src_inaddr) >> 24) & 0xff,/* address of foreign host */
- ((ip->src_inaddr) >> 16) & 0xff,/* address of foreign host */
- ((ip->src_inaddr) >> 8) & 0xff,/* address of foreign host */
- ((ip->src_inaddr)) & 0xff,/* address of foreign host */
- ((ip->dst_inaddr) >> 24) & 0xff,
- ((ip->dst_inaddr) >> 16) & 0xff,
- ((ip->dst_inaddr) >> 8) & 0xff,
- ((ip->dst_inaddr)) & 0xff);
- log(text);
- }
- }
- }
- }
-
- char *pr_ipprot(int prot)
- {
- static char portstr[10];
-
- switch(prot)
- {
- case IP_ICMP:
- return("ICMP");
-
- case IP_GGP:
- return("GGP");
-
- case IP_ST:
- return("ST");
-
- case IP_TCP:
- return("TCP");
-
- case IP_UDP:
- return("UDP");
-
- default:
- return(itoa(prot,portstr,10));
- }
- }
-
- int print_tcb(TCP_TCB *tcb_list)
- {
- char str1[10],str2[10];
-
- sprintf(text,"%2d %c %6s %3ld.%3ld.%3ld.%3ld.%6s %5lu/%-5lu %5lu/%-5lu %s",
- tcb_list->handle,
- tcb_list->active ? 'A' : 'P', /* this connection is active/listening only */
- pr_tcpport(tcb_list->lcl_port,str1), /* my portnumber */
- ((tcb_list->fhost) >> 24) & 0xff,/* address of foreign host */
- ((tcb_list->fhost) >> 16) & 0xff,/* address of foreign host */
- ((tcb_list->fhost) >> 8) & 0xff,/* address of foreign host */
- ((tcb_list->fhost)) & 0xff,/* address of foreign host */
- pr_tcpport(tcb_list->fgn_port,str2), /* portnumber of foreign host */
- q_used(&tcb_list->q_out), /* output queue */
- tcb_list->q_out.size-1,
- q_used(&tcb_list->q_in), /* input queue */
- tcb_list->q_in.size-1,
- pr_state(tcb_list->state)); /* statusblocke of transmission */
- log(text);
- return(0);
- }
-
- int print_udp(UDP_CTL *udp_list)
- {
- char str1[10],str2[10];
-
- sprintf(text,"%2d U %6s %3ld.%3ld.%3ld.%3ld.%6s %-5u",
- udp_list->handle,
- pr_udpport(udp_list->lcl_port,str1), /* my portnumber */
- ((udp_list->fhost) >> 24) & 0xff,/* address of foreign host */
- ((udp_list->fhost) >> 16) & 0xff,/* address of foreign host */
- ((udp_list->fhost) >> 8) & 0xff,/* address of foreign host */
- ((udp_list->fhost)) & 0xff,/* address of foreign host */
- pr_udpport(udp_list->fgn_port,str2), /* portnumber of foreign host */
- udp_list->data_len);
- log(text);
- return(0);
- }
-
- char *pr_tcpport(int port, char portstr[10])
- {
- switch(port)
- {
- case FTP_CTL:
- return("ftpctl");
-
- case FTP_DATA:
- return("ftpdta");
-
- case TELNET:
- return("telnet");
-
- default:
- return(ultoa(((unsigned long)port & 0xFFFF),portstr,10));
- }
- }
- char *pr_udpport(int port,char portstr[10])
- {
-
- switch(port)
- {
- case NAMESERV_IEN116:
- return("NAMIEN");
-
- case NAMESERV_RFC:
- return("NAMRFC");
-
- default:
- return(ultoa(((unsigned long)port & 0xFFFF),portstr,10));
- }
- }
-
- char *pr_state(int state)
- {
- static char *states[11]=
- {
- "CLOSED",
- "LISTEN",
- "SYNSENT",
- "SYNREC",
- "ESTABLISHED",
- "FINWAIT1",
- "FINWAIT2",
- "CLOSEWAIT",
- "CLOSING",
- "LASTACK",
- "TIMEWAIT"
- };
- return(states[state]);
- }
-